package futbol.tacticas.concursantes.TacticaJulioEnrique;
/*
 * TacticaJulioEnrique.java
 *
 * Created on 3 de mayo de 2008, 10:22
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

import futbol.General;
import java.awt.*;
import java.awt.geom.Arc2D.Double;
import java.lang.reflect.Array;
import java.sql.Date;
import java.util.Arrays;
import java.util.Random;
import java.util.Vector;


import futbol.tacticas.*;
import futbol.tacticas.concursantes.Tactica;
/**
 *
 * @author Administrador
 */
public class TacticaJulioEnrique implements Tactica{
    
	
	int[] asignFix=new int[]{-2,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2};
	long marcador;
	double[] velocidadContrarios = new double[11];
    Point[] posicionContrarios = new Point[11];
    boolean setPosC=false;
    boolean setVelocCont=false;
    boolean speedFound=false;
	private SituacionPelota sp=new SituacionPelota();
    private int nValores[][]={
    		{-152,0,5},
            {-100,100,6},
            {-120,30,6},
            {-120,-30,6},        
            {-100,-100,6},
            {20,60,7},
            {-20,0,7},
            {70,0,7},
            {20,-60,7},
            {120,30,7},
            {100,-60,7}
    };
    
    private int limitePase[]=
    {
    		0,
    		20,
    		20,
    		20,
    		20,
    		10,
    		10,
    		10,
    		10,
    		-30,
    		-30,
    };
    
    private ZonaCampo zone[]=
    {
    		null,
    		new ZonaCampo(0,-160,70,120),
    		new ZonaCampo(-20,-140,-10,100),
    		new ZonaCampo(-20,-140,-100,10),
    		new ZonaCampo(0,-160,-120,-70),
    		new ZonaCampo(150,-120,10,120),
    		new ZonaCampo(100,-120,-40,40),
    		new ZonaCampo(140,0,-70,70),
    		new ZonaCampo(150,-120,-120,-10),
    		new ZonaCampo(160,20,-20,120),
    		new ZonaCampo(160,20,-120,20),
     };
    
    private boolean moved[]=
    {
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
     };
    
    boolean pocaFuerzaAct=true; 
    
    private boolean hitted[]=
    {
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
    		false,
     };
    
    
    public Color getColor1() {
        return Color.white;
    }

    public Color getColor2() {
        return Color.white;
    }

    public Color getColorNumero() {
        return Color.blue;
    }

    public String getNombre() {
        return "RealMatanzas";
    }

    public int getXInicial(int n) {
        return nValores[n][0];
    }

    public int getYInicial(int n) {
        return nValores[n][1];
    }

    public int getFuerza(int n) {
        return nValores[n][2];
    }

    public Vector<Comando> getComandos(SituacionJugadores sj) {
        Vector<Comando> com=new Vector();
        //Posicionamiento
        marcador++;
        getVelocidadesContrarios(sj);
        if(marcador==2)
        {
        	calibraFuerza();
        }
        
        if(marcador>2){
        for (int n=0;n<11;n++){
            com.add(new ComandoIrA(n,nValores[n][0],nValores[n][1]));
            moved[n]=false;
        }
        Point bola=sj.getBola();
        Point jugadores[]=sj.getMisJugadores();
        Point contrarios[]=sj.getContrario();
        sp.setPoint(bola);
        
        
        
//    	Movimiento mas cercano a la bola
        int nJug=sj.getMasCercanoDeBola();
        Point finalBola=getPosicionFinalBola();
        int nJug2=sj.getMiJugadorMasCerca(finalBola.x, finalBola.y);
        
        if(nJug==0)
        {
        	nJug=sj.getSiguienteJugador(nJug);        	
        }
        
        Point resulta=new Point();
        //com.add(new ComandoIrA(nJug,bola.getX(),bola.getY()));
        resulta=this.getPuntoMasCercaNumericoMejorado(bola,jugadores[nJug],10-this.getFuerza(nJug));
		com.add(new ComandoIrA(nJug,resulta.getX(),resulta.getY()));
        moved[nJug]=true;
        
     
//      Mejorar defensa
        for (int n=1;n<5;n++)
        {
        	if(!moved[n])
            {
            	boolean result=zone[n].inZone(bola);
            	
            	if(result)
            	{
            		Point myPos=jugadores[n];
            		Point cerca=this.getPuntoMasCercaNumericoMejorado(bola,myPos,10-this.getFuerza(n));
            		com.add(new ComandoIrA(n,cerca.getX(),cerca.getY()));
            		moved[n]=true;
            	}
            }
        	if(jugadores[n].x<=-30){
        	zone[n].moveZone(jugadores[n]);
        	}
        	else
        	{
        		Point pZone=new Point();
        		pZone.setLocation(nValores[n][0],nValores[n][1]);
        		zone[n].moveZone(pZone);
        	}
        }
        
        if(!moved[nJug2] && nJug2!=0)
        {
        	com.add(new ComandoIrA(nJug2, finalBola.x, finalBola.y));
        	moved[nJug2]=true;
        }
        
        for (int n=5;n<11;n++){
            if(!moved[n] && zone[n]!=null)
            {
            	boolean result=zone[n].inZone(bola);
            	
            	if(result)
            	{
            		resulta=this.getPuntoMasCercaNumericoMejorado(bola,jugadores[n],10-this.getFuerza(n));
            		com.add(new ComandoIrA(n,resulta.getX(),resulta.getY()));
            		moved[n]=true;
            	}
            }
        }
        
        Vector<Integer> cont=new Vector();
        
        int limiteDefensa=-30;
		for(int i=0;i<11;i++)
		{
			if(contrarios[i].x<limiteDefensa){
				cont.add(i);
			}
		}
		
		if(cont.size()>4 && asignFix[6]==-2)
		{
			asignFix[6]=-1;
		}
		
		if(cont.size()<=4 && asignFix[6]>-2)
		{
			asignFix[6]=-2;
		}
		
		//System.out.println(cont.size());
		for(int i=0;i<11;i++)
		{
			if(asignFix[i]>-1)
			{
				if(!cont.contains(asignFix[i]))
				{
					asignFix[i]=-1;
				}
				else
				{
					cont.removeElement(asignFix[i]);
				}
			}
		}
		
		Integer[] inte=new Integer[cont.size()];
		int[] contArr=new int[cont.size()];
		inte=cont.toArray(inte);
		for(int i=0;i<inte.length;i++)
		{
			contArr[i]=inte[i].intValue();
		}
		Ordena(contArr,new CriterioY(),contrarios);
		
		for(int j=0;j<contArr.length;j++)
		{
			int menor=Menor(contrarios[contArr[j]],jugadores,asignFix);
			if(menor>=0 && menor<=10)
			{
				asignFix[menor]=contArr[j];	
			}
		}
		
		int defCount=0;
		double promY=0;
		int sel=0;
		for(int n=0;n<11;n++)
        {       	
        	if(asignFix[n]>0)
        	{
        		defCount++;
        		if(!moved[n])
        		{
        			cubre(n,asignFix[n],sj,com);
        			moved[n]=true;
        		}
        	}
        }
        
		if(defCount==3)
    	{
			//System.out.println("3");
			for(int k=1;k<=4;k++)
    		{
    			if(asignFix[k]==-1)
    			{
    				if(!moved[k])
    					sel=k;
    				else
    					sel=-1;
    				
    			}
    			else
    			{
    				promY+=jugadores[k].y;
    			}
    		}
    		if(sel>0){
    			promY/=3;
    			com.add(new ComandoIrA(sel,nValores[2][0],promY));
    			//System.out.println(promY);
    		}
 }
        
       
        
        for(int n=7;n<11;n++)
        {
        	if(!moved[n])
        	{
        		double sumX=0;
        		double sumY=0;
        		double centroEquipoX=0;
        		double centroEquipoY=0;
        		double incrementoEquipoX=0;
        		double incrementoEquipoY=0;
        		
        		for (int i=0;i<11;i++)
        	    {
        	        sumX += jugadores[i].getX();
        	        sumY += jugadores[i].getY();
        	    }
        	    centroEquipoX = sumX/11;
        	    centroEquipoY = sumY/11;

        	    incrementoEquipoX = -(centroEquipoX - bola.getX())/2;
        	    incrementoEquipoY = -(centroEquipoY - bola.getY())/2;
        	    incrementoEquipoX/=4;
        	    com.add(new ComandoIrA(n,nValores[n][0]+incrementoEquipoX/2,nValores[n][1]+incrementoEquipoY));
        	}
        	if(n==7)n++;
        }
        
        //Movimiento portero
       
        
        
       if(salePortero(sj))
        	{
        		com.add(new ComandoIrA(0,bola.getX(), bola.getY()));
        	}
       else
        	{
     			int y=(int)this.cerrarAngulo(bola);
       			com.add(new ComandoIrA(0,nValores[0][0], y));
        	}
       moved[0]=true;
       
       
//        }
        

            
        lanzarBolaMejor(sj, com, nJug);
        lanzarBolaPortero(sj,com);
        
        
        }
        return com;
    }
   
    public int Menor(Point p,Point[] mios,int[] marcados)
    {
    	double min=java.lang.Double.MAX_VALUE;
    	int indMin=-1;
    	
    	for(int i=0;i<11;i++){
    		if(marcados[i]==-1){
    			double dist=General.getDistancia(p.x,p.y,mios[i].x,mios[i].y);
    			if(dist<min)
    			{
    				min=dist;
    				indMin=i;
    			}
    		}
    	}
    	
    	return indMin;
    }
  
public boolean vectoresIguales(Vector<Integer> v1,Vector<Integer> v2)
{
	if(v1.size()!=v2.size())return false;
	for(int i=0;i<v1.size();i++)
	{
		if(v1.get(i)!=v2.get(i))return false;
	}
	return true;
	
}
    
public void Ordena(int[] who,Criterio c,Point[] contrarios)
{
	Point[] p=new Point[who.length];
	for(int i=0;i<p.length;i++)
	{
		p[i]=contrarios[who[i]];
	}
	
	for(int i=0;i<p.length-1;i++)
	{
		for(int j=i+1;j<p.length;j++)
		{
			if(c.Compara(p[i],p[j])<1)
			{
				Point temp=p[i];
				p[i]=p[j];
				p[j]=temp;
			}
		}
	}
}

public void calibraFuerza()
{
	double promCont=hallarPromedio(velocidadContrarios,1,8);
	double[] myVeloc=new double[11];
	for(int i=0;i<11;i++)
	{
		myVeloc[i]=10-nValores[i][2];
	}
	
	double promMio=hallarPromedio(myVeloc,1,8);
	if(promMio+1>promCont)
	{
		pocaFuerzaAct=true;
	}
	else
	{
		pocaFuerzaAct=false;
	}
	//System.out.println("mi promedio: "+promMio+" el del contrario: "+promCont+" poca fuerza activada: "+pocaFuerzaAct);
}

public double hallarPromedio(double[] veloc,int desde,int hasta)
{
	double promedio=0;
	for(int i=desde;i<=hasta;i++)
	{
		promedio+=veloc[i];
	}
	return promedio/(hasta-desde+1);
}

public void cubre(int nJug, int nCon, SituacionJugadores sj, Vector<Comando> com)
{
		double x = sj.getBola().getX() - sj.getContrario()[nCon].getX();
		double y = sj.getBola().getY() - sj.getContrario()[nCon].getY();
        Point bola= sj.getBola();
        Point contrario = sj.getContrario()[nCon];
        double n = General.getDistancia(bola.x,bola.y,contrario.x,contrario.y);
        double nx = sj.getContrario()[nCon].getX()+(x/n)*15;
        double ny = sj.getContrario()[nCon].getY()+(y/n)*15;
        com.add(new ComandoIrA(nJug,(int)nx,(int)ny));
        
}
    
 private void GolpearBolaMejorado(SituacionJugadores sj,Vector<Comando> com, int nJug,int x,int y,int fuerza){       
    	Point myJug=sj.getMisJugadores()[nJug];
    	double dx=x-myJug.x;
        double dy=y-myJug.y;
        //fuerza=getFuerza(nJug);
        if (dx!=0 && dy!=0){
            double dist=General.getDistancia(x,y,myJug.x,myJug.y);
            dx=dx/dist;dy=dy/dist;
            int f=Math.min(getFuerza(nJug),fuerza);
            double d=50d*(double)f/(double)getFuerza(nJug);
            double dd=d,ddx=dx,ddy=dy;
            int ff;
            do{
                dx=(int)((double)ddx*dd);
                dy=(int)((double)ddy*dd);
                dist=Math.sqrt(dx*dx+dy*dy);
                ff=getFuerza(nJug)*(int)dist/52;
                dd++;
            } while (ff<f);
            
            com.add(new ComandoGolpearBola(nJug,myJug.x+dx,myJug.y+dy));
            
        } else
        	com.add(new ComandoGolpearBola(nJug,myJug.x,myJug.y));
    }
    
    private double cerrarAngulo(Point bola)
    {
    	double y1;
    	if(bola.getX()>0)
    	{
    		bola.x=0;
    		y1=-53*bola.getY()/(-213+bola.getX());
    	}
    	else
    	{
    		y1=sp.Interpol(-160);
    		if(Math.abs(y1)>60)
    		{
    			y1=-53*bola.getY()/(-213+bola.getX()); 
    		}
    	}
    	
    	return y1;
    }
    
    private double getCoeficienteContrarioCerca(SituacionJugadores sj, int actual)
    {
    	Point cont=sj.getContrario()[sj.getContrarioMasCerca(actual)];
    	Point yo=sj.getMisJugadores()[actual];
    	double dist=General.getDistancia(yo.getX(),yo.getY(),cont.getX(),cont.getY());
    	if(dist>=35) return 1;
    	return dist/35;
    }
    
    private int AQuienPasoMejorado(SituacionJugadores sj, int actual)
    {
    	Vector<Integer> jugadores=new Vector();
    	Point[] losmios=sj.getMisJugadores();
    	int max=0;
    	double maxVal=0;
    	
    	for(int i=1;i<11;i++)
    	{
    		if(i!=actual && (losmios[i].getX()-limitePase[actual])>losmios[actual].getX())
    		{
    			jugadores.addElement(new Integer(i));
    		}
    	}
    	if(jugadores.size()==0)
    	{
    		return -1;
    	}
    	
    	
    	double[] puntos=new double[jugadores.size()];
    	for(int i=0;i<jugadores.size();i++)
    	{
    		puntos[i]=0.4*(1-(this.cantidadContrariosEnDespejeMejorado(sj,losmios[actual],losmios[jugadores.get(i).intValue()])/11.0));   		
    		puntos[i]+=0.2*(losmios[jugadores.get(i).intValue()].getX()/160);
    		puntos[i]+=0.3*(1-(General.getDistancia(losmios[actual].getX(),losmios[actual].getY(),losmios[jugadores.get(i).intValue()].getX(),losmios[jugadores.get(i).intValue()].getY())/400));
    		puntos[i]+=0.1*getCoeficienteContrarioCerca(sj,actual);
    		puntos[i]+=0.1*Math.abs(losmios[jugadores.get(i).intValue()].getY())/120;
    	}
    	
    	for(int i=0;i<puntos.length;i++)
    	{
    		if(puntos[i]>maxVal)
    		{
    			max=i;
    			maxVal=puntos[i];
    		}
    	}
    	return jugadores.get(max).intValue();
    }
    
    private int AQuienPasoExigenteMejorado(SituacionJugadores sj, int actual)
    {
    	Vector<Integer> jugadores=new Vector();
    	Point[] losmios=sj.getMisJugadores();
    	int max=-1;
    	double maxVal=0;
    	
    	for(int i=1;i<11;i++)
    	{
    		if(i!=actual && (losmios[i].getX()-limitePase[actual])>losmios[actual].getX())
    		{
    			jugadores.addElement(new Integer(i));
    		}
    	}
    	if(jugadores.size()==0)
    	{
    		return -1;
    	}
    	
    	
    	double[] puntos=new double[jugadores.size()];
    	for(int i=0;i<jugadores.size();i++)
    	{
    		puntos[i]=0.4*(1-(this.cantidadContrariosEnDespejeMejorado(sj,losmios[actual],losmios[jugadores.get(i).intValue()])/11.0));
    		
    		puntos[i]+=0.2*(losmios[jugadores.get(i).intValue()].getX()/160);
    		puntos[i]+=0.3*(1-(General.getDistancia(losmios[actual].getX(),losmios[actual].getY(),losmios[jugadores.get(i).intValue()].getX(),losmios[jugadores.get(i).intValue()].getY())/400));
    		puntos[i]+=0.1*getCoeficienteContrarioCerca(sj,actual);
    		puntos[i]+=0.1*Math.abs(losmios[jugadores.get(i).intValue()].getY())/120;
    	}
    	
    	for(int i=0;i<puntos.length;i++)
    	{
    		if(puntos[i]>maxVal && puntos[i]>0.665)
    		{
    			max=i;
    			maxVal=puntos[i];
    		}
    	}
    	if(max==-1)return max;
    	
    	return jugadores.get(max).intValue();
    }
    
    private int getFuerzaGolpe(double dist,int fuerzaJug)
    {
    	int fuerza;
    	if(!pocaFuerzaAct) return fuerzaJug;
        if (dist>90)
            fuerza=7;
        else if (dist>40)
            fuerza=6;
        else fuerza=4;
        return fuerza;
    }
   
    private void lanzarBolaMejor(SituacionJugadores sj, Vector<Comando> com,int nJug){
        Point bola=sj.getBola();
        Point jug[]=sj.getMisJugadores();
        Point ene[]=sj.getContrario();
        int nDir[][]={{20,0},
                    {13,13},
                    {13,-13},
                    {-13,13},
                    {0,-20},
                    {0,20},
                    {-13,-13},
                    {-20,0}};
        
         int nDis=40;
         hitted[nJug]=false;
         
         
        if (jug[nJug].getX()>50)
        {
                com.add(new ComandoTiroAPuerta(nJug,15));
                hitted[nJug]=true;
        }
        
        


        if(!hitted[nJug])
            {
                int res=AQuienPasoExigenteMejorado(sj,nJug);
                if(res==-1)
                {
                	
                	 if (!hitted[nJug] && General.getDistancia(bola.getX(), bola.getY(), jug[nJug].getX(), jug[nJug].getY())<15) 
                	        
                     	for (int n=0;n<nDir.length && !hitted[nJug] ;n++){
                             double xN=corregirLateral(160,jug[nJug].getX()+nDir[n][0]);
                             double yN=corregirLateral(120,jug[nJug].getY()+nDir[n][1]);
                             int nJC= sj.getContrarioMasCerca(xN, yN);
                             if (General.getDistancia(xN, yN, ene[nJC].getX(), ene[nJC].getY())>nDis){
                                 
                            	 com.add(new ComandoGolpearBola(nJug, xN, yN));
                                 hitted[nJug]=true;
                                 break;
                             }
                         }
                	if(!hitted[nJug])
                	{
                		int res1=AQuienPasoMejorado(sj,nJug);
                        if(res1==-1)
                        {
                        	com.add(new ComandoTiroAPuerta(nJug,15));
                        	hitted[nJug]=true;
                        }
                        else
                        {
                        	Point tiene=sj.getMisJugadores()[nJug];
                        	Point aQuien=sj.getMisJugadores()[res1];
                        	GolpearBolaMejorado(sj,com,nJug,aQuien.x,aQuien.y,getFuerzaGolpe(General.getDistancia(tiene.x,tiene.y,aQuien.x,aQuien.y),getFuerza(nJug)));
                        	
                        	//com.add(new ComandoPase(nJug,res1));
                        	hitted[nJug]=true;
                        }
                	}
                }
                else
                {
                	Point tiene=sj.getMisJugadores()[nJug];
                	Point aQuien=sj.getMisJugadores()[res];
                	GolpearBolaMejorado(sj,com,nJug,aQuien.x,aQuien.y,getFuerzaGolpe(General.getDistancia(tiene.x,tiene.y,aQuien.x,aQuien.y),getFuerza(nJug)));
                	
                	//com.add(new ComandoPase(nJug,res));
                	hitted[nJug]=true;
                } 	
            }     
}
    
    
    public void getVelocidadesContrarios(SituacionJugadores sj){
        if (!setPosC) {
            posicionContrarios=sj.getContrario();
            setPosC=true;
        }
        else if (setPosC && !setVelocCont) {
            for (int i=0;i<11;i++){
            velocidadContrarios[i] = Math.round(General.getDistancia(posicionContrarios[i].x,posicionContrarios[i].y,sj.getContrario()[i].x,sj.getContrario()[i].y));
            //if ((velocidadContrarios[i]<3)||(velocidadContrarios[i]>6)) velocidadContrarios[i]=6;
            //System.out.println(velocidadContrarios[i]);
            setVelocCont=true;
            }
            speedFound=hallarPromedio(velocidadContrarios,1,8)!=0;
            
        }
        if(setPosC && setVelocCont && !speedFound)
        {
        	setPosC=false;
        	setVelocCont=false;
        }
    }
    
    
    private boolean salePortero(SituacionJugadores sj)
    {
    	Point bola=sj.getBola();
    	if(bola.getX()<-100 && Math.abs(bola.getY())<80)
    	{
       		
    		if(sj.getMasCercanoDeBola()==0 && sp.getVelocidad()<=15)
    			return true;
    		else if(!sj.estoyMasCercaDeBola() && this.miDefensaEstaPorDelante(sj,bola) && sp.getVelocidad()<=15)
    		{
    			return true;
    		}
    	}
    	return false;
    }
    
    private boolean miDefensaEstaPorDelante(SituacionJugadores sj,Point bola)
    {
    	Point[] losmios=sj.getMisJugadores();
		for(int i=1;i<=10;i++)
		{
			if(bola.distance(losmios[i].getX(),losmios[i].getY())<10)
			{
				if(bola.getX()>losmios[i].getX()) return false;
			}
		}
    	return true;
    }
    private Point[] getContrariosAMenorDist(SituacionJugadores sj,Point punto, double dist)
    {
    	Point[] contrario=sj.getContrario();
    	Vector<Point> jugadores=new Vector();
    	
    	for(int i=0;i<contrario.length;i++)
    	{
    		if(General.getDistancia(punto.getX(),punto.getY(),contrario[i].getX(),contrario[i].getY())<dist)
    		{
    			jugadores.add(contrario[i]);
    		}
    	}
    	Point[] result=new Point[jugadores.size()];
    	return jugadores.toArray(result);
    }
    
    private int cantidadContrariosEnDespejeMejorado(SituacionJugadores sj,Point bola,Point despeje)
    {
    	double distancia=General.getDistancia(bola.getX(),bola.getY(),despeje.getX(),despeje.getY());
    	if(distancia==0)
    	{
    		return 0;
    	}
    	double inc=distancia/30.0;
    	Vector<Point> jugadores=new Vector();
    	Point actual=new Point();
    	double angulo=General.getAngulo(bola.getX(),bola.getY(),despeje.getX(),despeje.getY());
    	
    	for(double i=0;i<=distancia;i+=inc)
    	{
    		
    		actual.setLocation(bola.getX()+i*Math.cos(angulo),bola.getY()+i*Math.sin(angulo));
    		Point[] tempArray=getContrariosAMenorDist(sj,actual,30);
    		for(int j=0;j<tempArray.length;j++)
    		{
    			if(!jugadores.contains(tempArray[j]))
        		{
        			jugadores.addElement(tempArray[j]);
        		}
    		}
    	}
    	return jugadores.size();
    }
    
    
    
    
    public double corregirLateral(double limite, double x){
        if (x>limite) return limite*2-x;
        if (x<-limite) return -limite*2-x;
        return x;
    }
    
    
    
    private void lanzarBolaPortero(SituacionJugadores sj, Vector<Comando> com)
    {
        
       	Point tiene=sj.getMisJugadores()[0];
   		Point aQuien=sj.getMisJugadores()[AQuienPasoMejorado(sj,0)];
   		GolpearBolaMejorado(sj,com,0,aQuien.x,aQuien.y,getFuerzaGolpe(General.getDistancia(tiene.x,tiene.y,aQuien.x,aQuien.y),getFuerza(0)));            
    }
 
    public Point getPuntoMasCercaNumericoMejorado(Point bola, Point jug,int speedJugador)
    {
    	double xJug=0;
    	double xBola=0;
    	Point pActBola=new Point();
    	Point pUltBola=new Point();
    	
    	pActBola.setLocation(bola.getX(),bola.getY());    	
    	double veloc=sp.getVelocidad();
    	double angulo=General.getAngulo(sp.getViejo().getX(),sp.getViejo().getY(),sp.getNuevo().getX(),sp.getNuevo().getY());
    	pUltBola.setLocation(bola.getX(),bola.getY());    	
    	
    	//System.out.println("viejo:"+sp.viejo.getX()+";"+sp.viejo.getY()+" nuevo:"+sp.nuevo.getX()+";"+sp.nuevo.getY());
    	if(veloc==0)
    	{
    		return bola;
    	}
    	
    	for(int t=1;General.getDistancia(pActBola.getX(),pActBola.getY(),jug.getX(),jug.getY())>xJug+10;t++)
    	{
    		xJug+=speedJugador;
    		xBola=veloc;
    		pUltBola.setLocation(pActBola.getX(),pActBola.getY());    		
    		pActBola.setLocation(pActBola.getX()+xBola*Math.cos(angulo),pActBola.getY()+xBola*Math.sin(angulo));
    		
    		if (pActBola.getX()>160){
                pActBola.setLocation(320-pActBola.getX(),pActBola.getY());
                angulo=General.corregirAngulo(Math.PI-angulo);
                
            }
            if (pActBola.getX()<-160){
            	pActBola.setLocation(-320-pActBola.getX(),pActBola.getY());
            	angulo=General.corregirAngulo(Math.PI-angulo);
            	
            }
            if (pActBola.getY()>120){
            	pActBola.setLocation(pActBola.getX(),240-pActBola.getY());
            	angulo=General.corregirAngulo(-angulo);
            	
            }
            if (pActBola.getY()<-120){
            	pActBola.setLocation(pActBola.getX(),-240-pActBola.getY());
            	angulo=General.corregirAngulo(-angulo);
            	
            }
    		
            if(veloc>0)veloc--;
    	}
    	
    	if(General.getDistancia(pActBola.getX(),pActBola.getY(),jug.getX(),jug.getY())<(xJug+10))
    	{
    		return pActBola;
    	}
    	else
    	{
    		/*Point pResult=new Point();
    		pResult.setLocation((pActBola.getX()+pUltBola.getX())/2,(pActBola.getY()+pUltBola.getY())/2);
    		return pResult;*/
    		return pActBola;
    		
    		
    	}
    	
    }
    
    
    private Point getPosicionFinalBola()
    {
    	double x=sp.nuevo.x;
    	double y=sp.nuevo.y;
    	double xAnt=sp.viejo.x;
    	double yAnt=sp.viejo.y;
    	double distancia=sp.getVelocidad();
    	
        if(distancia>1)
        do
        {
            double xAux = x;
            double yAux = y;
            x = x+(x-xAnt)*(distancia-1)/(distancia);
            y = y+(y-yAnt)*(distancia-1)/(distancia);
            xAnt = xAux;
            yAnt = yAux;
            
            if (x>=160 && y>-30 && y<30) 
            {
            	Point p=new Point();
            	p.setLocation(x,y);
            	return p;
            }
            if (x<=-160 && y>-30 && y<30)
            {
            	Point p=new Point();
            	p.setLocation(x,y);
            	return p;
            }

            // Corregir
            if (x>160){
                x=320-x;  //160 - (x-160)
                xAnt=320-xAnt;  //160 - (x-160)
            }
            if (x<-160){
                x=-320-x; //-160 + (-160-x)
                xAnt=-320-xAnt; //-160 + (-160-x)
            }
            if (y>120){
                y=240-y; //120 - (x-120)
                yAnt=240-yAnt; //120 - (x-120)
            }
            if (y<-120){
                y=-240-y;  //-120 + (-120-x)
                yAnt=-240-yAnt;  //-120 + (-120-x)
            }
            distancia = General.getDistancia(xAnt, yAnt, x, y);
        } while(distancia>=10);
        Point p=new Point();
    	p.setLocation(x,y);
    	return p;
       
    }
    
}
class SituacionPelota
{
	Point viejo;
	Point nuevo;
	
	public SituacionPelota()
	{
		viejo=new Point();
		viejo.setLocation(0,0);
		nuevo=new Point();
		nuevo.setLocation(0,0);
	}
	
	public Point getViejo()
	{
		return viejo;
	}
	
	public Point getNuevo()
	{
		return nuevo;
	}
	
	public void setPoint(Point p)
	{
		viejo.setLocation(nuevo.x,nuevo.y);
		nuevo.setLocation(p.x,p.y);
		
	}
	
	public double Interpol(double x)
	{
		if(viejo.getX()==nuevo.getX())
		{
			return -1000;
		}
		double lx=0;
		double ly=0;
		lx=viejo.getX()-nuevo.getX();
		ly=viejo.getY()-nuevo.getY();
		if(lx<0) return -1000;
		double yres=(viejo.getX()+160)*ly/lx;
		return viejo.getY()-yres;
	}
	
	public double getVelocidad()
	{
		return General.getDistancia(viejo.getX(),viejo.getY(),nuevo.getX(),nuevo.getY());
	}
	
	public double getAceleracion()
	{
		return -1;
	}
	
	public double getM()
	{
		if(viejo.getX()==nuevo.getX())
		{
			return java.lang.Double.MAX_VALUE/100;
		}
		return (viejo.getY()-nuevo.getY())/(viejo.getX()-nuevo.getX());
	}
	
	public double getN()
	{
		return viejo.getY()-getM()*viejo.getX();
	}
	
}

abstract class  Criterio
{
	public abstract int Compara(Point p1,Point p2);
	
}

class CriterioY extends Criterio
{
	public int Compara(Point p1,Point p2)
	{
		if(p1.y>p2.y)return 1;
		else if(p1.y==p2.y) return 0;
		else return -1;
	}
}

class ZonaCampo
{
	double limiteAdelante;
	double limiteAtras;
	double limiteIzq;
	double limiteDer;
	
	public ZonaCampo(double ladelant,double latras,double lizq,double lder)
	{
		if(ladelant>160 || latras<-160 || lizq<-120 || lder>120 || ladelant<latras || lder<lizq)
			{}
		
		limiteAdelante=ladelant;
		limiteAtras=latras;
		limiteIzq=lizq;
		limiteDer=lder;
	}
	
	public Point getCenter()
	{
		Point result=new Point();
		
		result.x=(int)((limiteAdelante+limiteAtras)/2);
		result.y=(int)((limiteIzq+limiteDer)/2);
		return result;
	}
	
	public double getLimiteDelantero()
	{
		return limiteAdelante;
	}
	
	public double getLimiteAtras()
	{
		return limiteAtras;
	}
	
	public double getLimiteIzq()
	{
		return limiteIzq;
	}
	
	public double getLimiteDer()
	{
		return limiteDer;
	}
	
	public boolean inZone(Point p)
	{
		return (p.getX()<limiteAdelante && p.getX()>limiteAtras && p.getY()<limiteDer && p.getY()>limiteIzq);
	}
	
	public void moveZone(Point p)
	{
		Point center=this.getCenter();
		double xMove=p.x-center.x;
		double yMove=p.y-center.y;
		
		limiteIzq+=yMove;
		limiteDer+=yMove;
		limiteAdelante+=xMove;
		limiteAtras+=xMove;
	}
	
	
	
}